package com.compmov.webservice;

import java.net.ServerSocket;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.compmov.datamodel.Foto;
import com.compmov.datamodel.Persona;
import com.compmov.libraries.QueryParamDictionary;
import com.google.gson.Gson;

public class PersonaWSClient {

	private WebServiceClient webService;
	private static final String TAG = "WEBSERVICE";
	
	
	public PersonaWSClient(String WSName) {
		super();
		webService = new WebServiceClient("/rest/"+WSName);
	}


	public PersonaWSClient(WebServiceClient webService) {
		super();
		this.webService = webService;
	}

	/**
	 * Obtiene la lista de todas las personas registradas en la base de datos del servidor
	 * @return Lista de personas registradas en el sistema
	 * @throws WSClientException	Si ocurre algun errro durante la ejecucion del web service
	 */
	public List<Persona> getAll() throws WSClientException {
		
		// Pass the parameters if needed , if not then pass dummy one as follows
		Map<String, String> params = new HashMap<String, String>();

		Log.d(TAG, "Invocando");
		//Obtener la respuesta en JSON del webService en el metodo señalado
		String response = webService.webGet("/getAll", params);
		Log.d(TAG, "RESPONSE");
		try {
			WSError error = new Gson().fromJson(response, WSError.class);
			// Si no hay ningun error se intenta parsear el contenido de la
			// respuesta
			if (error.getError_description() == null) {
				List<Persona> personas = new LinkedList<Persona>();
				try {
					// Crear un nuevo objeto JSON de la cadena del response
					JSONObject jsonObj = new JSONObject(response);
					// Obtener todas las personas que se encuentren en el
					// arreglo persona
					JSONArray jsonPersona = jsonObj.getJSONArray("persona");
					// Se recorre cada objeto de JSON para obtener a la persona
					// como tal
					for (int i = 0; i < jsonPersona.length(); i++) {
						// Se crea el objeto JSON correspondiente
						JSONObject persona = jsonPersona.getJSONObject(i);
						// Se parsea el objeto de JSON a la clase persona y se
						// agrega a la lista
						Persona per = new Gson().fromJson(persona.toString(),
								Persona.class);
						if (per.getId()!=0) personas.add(per);
					}
					//Se actualiza la URL de todas las fotografias
					for(Persona p:personas){
						p.setFotografia(WebServiceClient.getServerURL()+p.getFotografia());
					}
					Log.d(TAG, personas + "");
					return personas;
				} catch (JSONException e) {
					Log.e(TAG, e.getMessage(), e);
					throw new WSClientException(e);
				}
			} else {
				Log.e(TAG, error.getError_description()+"");
				throw new WSClientException(error);
			}
		} catch (Exception e) {
			Log.e(TAG, e.getMessage(), e);
			throw new WSClientException(e);
		}
	}
	
	/**
	 * Obtiene una persona en base al ID o nombre de usuario y password (Login)
	 * @param persona	Persona que se utilizara como filtro,
	 * @return	Un objeto de la persona almacenada en el servidor con todos sus datos llenos
	 * @throws WSClientException	Si ocurre algun error en el webservice, ver Log para mas detalles
	 */
	public Persona getPersona(Persona personaFilter)throws WSClientException {
		
		Gson gson = new Gson();
		// Pass the parameters if needed , if not then pass dummy one as follows
		Map<String, String> params = new HashMap<String, String>();
		String jsonCad = new Gson().toJson(personaFilter,Persona.class);
		params.put(QueryParamDictionary.PERSONA_PARAM, jsonCad);
		
		Log.d(TAG, "INVOCANDO GET PERSONA");
		String response = webService.webPut("/getByFilters", params);
		Log.d(TAG, "RESPONSE = " + response);
		try {
			WSError error = gson.fromJson(response, WSError.class);
			// Si no hay ningun error se intenta parsear el contenido de la
			// respuesta
			if (error.getError_description() == null) {
				try {
					// Crear un nuevo objeto JSON de la cadena del response
					JSONObject jsonObj = new JSONObject(response);

					Log.d(TAG,"JSONOBJ= "+jsonObj.toString());
					//Obtener a la persona en formato JSON
					JSONObject jsonPersonaObj = jsonObj.getJSONObject("persona");
					Log.d(TAG,"JSONOBJPERSONA= "+jsonPersonaObj.toString());
					Persona per = gson.fromJson(
							jsonPersonaObj.toString(), Persona.class);
					//Agregar la direccion del servidor a la de la imagen obtenida por el servidor
					per.setFotografia(WebServiceClient.getServerURL()+per.getFotografia());
					return per;
				} catch (JSONException e) {
					Log.e(TAG, e.getMessage(), e);
					throw new WSClientException(e);
				}
			} else {
				Log.e(TAG, error + "");
				throw new WSClientException(error);
			}
		} catch (Exception e) {
			Log.d(TAG, e.getMessage());
			throw new WSClientException(e);
		}
	}

	
	/**
	 * Obtiene todos los amigos de una persona
	 * @param persona	Persona a la cual se le obtendran sus amigos
	 * @return	Lista de amigos de la persona indicada
	 * @throws WSClientException	Si ocurre algun error en el servicio
	 */
	public List<Persona> getAllFriends(Persona personaFiltro) throws WSClientException {
		
		Gson gson = new Gson();
		// Pass the parameters if needed , if not then pass dummy one as follows
		Map<String, String> params = new HashMap<String, String>();
		params.put(QueryParamDictionary.PERSONA_ID_PARAM, personaFiltro.getId().toString());
		
		// webService.webGet("getMoreAllerts", params);
		Log.d(TAG, "Invocando");
		String response = webService.webGet("/getAllFriends", params);
		Log.d(TAG, "RESPONSE = " + response);
		try {
			WSError error = gson.fromJson(response, WSError.class);
			// Si no hay ningun error se intenta parsear el contenido de la
			// respuesta
			if (error.getError_description() == null) {
				List<Persona> personas = new LinkedList<Persona>();
				try {
					// Crear un nuevo objeto JSON de la cadena del response
					JSONObject jsonObj = new JSONObject(response);
					// Obtener todas las personas que se encuentren en el
					// arreglo persona
					JSONArray jsonPersona = jsonObj.optJSONArray("persona");
					// Se recorre cada objeto de JSON para obtener a la persona
					// como tal
					if (jsonPersona != null) {
						for (int i = 0; i < jsonPersona.length(); i++) {
							// Se crea el objeto JSON correspondiente
							JSONObject persona = jsonPersona.getJSONObject(i);
							// Se parsea el objeto de JSON a la clase persona y
							// se
							// agrega a la lista
							Persona persona2 = gson.fromJson(
									persona.toString(), Persona.class);
							personas.add(persona2);
						}
						
					}else{
						JSONObject jsonPersonaObj = jsonObj.getJSONObject("persona");
						
						Persona per = gson.fromJson(
								jsonPersonaObj.toString(), Persona.class);
						if (per.getId()!=0){
							personas.add(per);
						}
					}
					//Se actualiza la URL de todas las fotografias
					for(Persona p:personas){
						p.setFotografia(WebServiceClient.getServerURL()+p.getFotografia());
					}
					Log.d(TAG, personas + "");
					return personas;
				} catch (JSONException e) {
					Log.e(TAG, e.getMessage(), e);
					throw new WSClientException(e);
				}
			} else {
				Log.e(TAG, error + "");
				throw new WSClientException(error);
			}
		} catch (Exception e) {
			Log.d(TAG, e.getMessage());
			throw new WSClientException(e);
		}
	}
	
	/**
	 * Buscar Personas en base a diferentes filtros de busqueda o a los amigos de una persona en especifico:
	 * En caso que la persona cuente con un ID, los filtros posibles son:
	 * 		Nombre
	 * 		Usuario
	 * 		Correo
	 * @param persona	Persona que utilizara como filtro
	 * @return	Lista de las personas que coincidan con la busqueda
	 * @throws WSClientException	Si ocurre algun error durante la invocacion al servicio
	 */
	public List<Persona> buscaPersonas(Persona personaFilter) throws WSClientException {
		
		Gson gson = new Gson();
		// Pass the parameters if needed , if not then pass dummy one as follows
		Map<String, String> params = new HashMap<String, String>();
		String jsonCad = new Gson().toJson(personaFilter,Persona.class);
		params.put(QueryParamDictionary.PERSONA_PARAM, jsonCad);
		
		Log.d(TAG, "Invocando BUSCAR PERSONA");
		String response = webService.webPut("/getByFilters", params);
		Log.d(TAG, "RESPONSE = " + response);
		try {
			WSError error = gson.fromJson(response, WSError.class);
			// Si no hay ningun error se intenta parsear el contenido de la
			// respuesta
			if (error.getError_description() == null) {
				List<Persona> personas = new LinkedList<Persona>();
				try {
					// Crear un nuevo objeto JSON de la cadena del response
					JSONObject jsonObj = new JSONObject(response);
					// Obtener todas las personas que se encuentren en el
					// arreglo persona
					Log.d(TAG,"JSONOBJ= "+jsonObj.toString());
					
					JSONArray jsonPersona = jsonObj.optJSONArray("persona");
					// Se recorre cada objeto de JSON para obtener a la persona
					// como tal
					if (jsonPersona != null) {
						for (int i = 0; i < jsonPersona.length(); i++) {
							// Se crea el objeto JSON correspondiente
							JSONObject persona = jsonPersona.getJSONObject(i);
							// Se parsea el objeto de JSON a la clase persona y
							// se
							// agrega a la lista
							Persona persona2 = gson.fromJson(
									persona.toString(), Persona.class);
							personas.add(persona2);
						}
						
					}else{
						JSONObject jsonPersonaObj = jsonObj.getJSONObject("persona");
						Persona persona2 = gson.fromJson(
								jsonPersonaObj.toString(), Persona.class);
						if (persona2.getId()!=0){
							personas.add(persona2);
						}
					}
					
					//Se actualiza la URL de todas las fotografias
					for(Persona p:personas){
						p.setFotografia(WebServiceClient.getServerURL()+p.getFotografia());
					}
					Log.d(TAG, personas + "");
					return personas;
				} catch (JSONException e) {
					Log.e(TAG, e.getMessage(), e);
					throw new WSClientException(e);
				}
			} else {
				Log.e(TAG, error + "");
				throw new WSClientException(error);
			}
		} catch (Exception e) {
			Log.d(TAG, e.getMessage());
			throw new WSClientException(e);
		}
}
	
	/**
	 * Borra la relacion persona_amigo
	 * @param persona	Persona origen, Persona destino
	 * @return	True/False
	 * @throws WSClientException	Si ocurre algun error durante la invocacion al servicio
	 */

	public boolean quitaAmigo(int perori, int perdes)throws WSClientException {
		String response;
		Gson gson = new Gson();
		JSONObject jsonObj;		
		JSONObject friendShip;
		Persona friendShip2;
		
		List<Foto> fotos = new LinkedList<Foto>();
		
		Map<String,String> params = new HashMap<String,String>();
		Log.d(TAG,"Iniciando WEBSERVICE...");		
		params.put("perori", String.valueOf(perori));
		params.put("perdes", String.valueOf(perdes));
		
		response = webService.webGet("/deleteFriendShip", params);
		Log.d(TAG,"Response: "+response);
		
		try {
			WSError error = gson.fromJson(response, WSError.class);
			if (error.getError_description() == null){
				return true;
			}else{				
				if (error.getError_description().compareTo("No se encontro a la persona")==0){
					return false;
				}else{
					Log.e(TAG, error.getError_description()+"");
					throw new WSClientException(error);
				}
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			Log.e(TAG, e.getMessage(), e);
			throw new WSClientException(e);
		}		
	}

}
